package com.xsd.awen.utils;

import lombok.Data;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

// mvn exec:java -Dexec.mainClass="com.xsd.awen.utils.GenCode"
public class GenCode {

    private static String TPL_BASE_PATH;
    private static String SRC_BASE_PATH;
    private static String STATIC_BASE_PATH;

    private static String CHARSET = "UTF-8";

    static {
        String workingDir = System.getProperty("user.dir");
        TPL_BASE_PATH = workingDir+"\\src\\main\\resources\\tpl\\";
        SRC_BASE_PATH = workingDir+"\\src\\main\\java\\com\\xsd\\awen\\";

        STATIC_BASE_PATH = new File(workingDir).getParent()+"\\frontend\\";
    }

    public static void main(String[] args) throws Exception {
        if(false){
            System.out.println(888);
            return;
        }

        System.out.println("11111111111111111111111111111111111111111");

        GenVo vo = new GenCode().new GenVo();
        vo.setTableName("t_tk_user_task");
        vo.setEntityName("UserTask");
        vo.setHtmlModel("userTask");
        vo.setDesc("");

        initEntity(vo);
        initEntityVo(vo);
        initEntityPagePo(vo);
        initMapper(vo);
        initService(vo);
        initController(vo);

        //initListHtml(vo);
    }

    public static void initEntity(GenVo vo) throws Exception {
        List<GenColumn> columns = findColumns(vo.getTableName());

        String tplPath = TPL_BASE_PATH + "Entity.tpl";
        String srcPath = SRC_BASE_PATH + "domain\\entity\\"+vo.getEntityName()+".java";

        String entityTpl = FileUtils.readFileToString(getPath(tplPath),CHARSET);

        String properties = "";
        for (GenColumn column : columns){
            String cs = column.getColumnName().toLowerCase();
            if( cs.equals("id") || cs.equals("create_time") || cs.equals("update_time") )continue;

            if(properties.length()!=0){
                properties += "    ";
            }
            properties += "private "+dbTypeToJavaType(column.getDataType())+" "+columnToProperty(column.getColumnName())+";\r\n\r\n";
        }
        entityTpl = entityTpl.replace("//properties",properties);
        entityTpl = entityTpl.replace("EntityTpl",vo.getEntityName());
        entityTpl = entityTpl.replace("t_py_user",vo.getTableName());

        FileUtils.writeStringToFile(getPath(srcPath),entityTpl,CHARSET);
    }

    public static void initEntityVo(GenVo vo) throws Exception {
        String tplPath = TPL_BASE_PATH + "EntityVo.tpl";
        String srcPath = SRC_BASE_PATH + "domain\\vo\\"+vo.getEntityName()+"Vo.java";

        String entityTpl = FileUtils.readFileToString(getPath(tplPath),CHARSET);

        entityTpl = entityTpl.replace("User",vo.getEntityName());
        entityTpl = entityTpl.replace("user",Strings.firstLow(vo.getEntityName()));
        entityTpl = entityTpl.replace("EntityVoTpl",vo.getEntityName()+"Vo");


        FileUtils.writeStringToFile(getPath(srcPath),entityTpl,CHARSET);
    }

    public static void initEntityPagePo(GenVo vo) throws Exception {
        String tplPath = TPL_BASE_PATH + "EntityPagePo.tpl";
        String srcPath = SRC_BASE_PATH + "domain\\po\\"+vo.getEntityName()+"PagePo.java";

        String entityTpl = FileUtils.readFileToString(getPath(tplPath),CHARSET);

        entityTpl = entityTpl.replace("User",vo.getEntityName());
        entityTpl = entityTpl.replace("EntityPagePoTpl",vo.getEntityName()+"PagePo");

        FileUtils.writeStringToFile(getPath(srcPath),entityTpl,CHARSET);
    }

    public static void initMapper(GenVo vo) throws Exception {
        String tplPath = TPL_BASE_PATH + "Mapper.tpl";
        String srcPath = SRC_BASE_PATH + "mapper\\"+vo.getEntityName()+"Mapper.java";

        String entityTpl = FileUtils.readFileToString(getPath(tplPath),CHARSET);

        entityTpl = entityTpl.replace("t_py_user",vo.getTableName());
        entityTpl = entityTpl.replace("User",vo.getEntityName());
        entityTpl = entityTpl.replace("user.",Strings.firstLow(vo.getEntityName())+".");
        entityTpl = entityTpl.replace("user",Strings.firstLow(vo.getEntityName()));
        entityTpl = entityTpl.replace("MapperTpl",vo.getEntityName()+"Mapper");

        FileUtils.writeStringToFile(getPath(srcPath),entityTpl,CHARSET);
    }

    public static void initService(GenVo vo) throws Exception {
        String tplPath = TPL_BASE_PATH + "Service.tpl";
        String srcPath = SRC_BASE_PATH + "service\\"+vo.getEntityName()+"Service.java";

        String entityTpl = FileUtils.readFileToString(getPath(tplPath),CHARSET);

        entityTpl = entityTpl.replace("User",vo.getEntityName());
        entityTpl = entityTpl.replace("user",Strings.firstLow(vo.getEntityName()));
        entityTpl = entityTpl.replace("ServiceTpl",vo.getEntityName()+"Service");

        FileUtils.writeStringToFile(getPath(srcPath),entityTpl,CHARSET);
    }

    public static void initController(GenVo vo) throws Exception {
        String tplPath = TPL_BASE_PATH + "Controller.tpl";
        String srcPath = SRC_BASE_PATH + "web\\"+vo.getEntityName()+"Controller.java";

        String entityTpl = FileUtils.readFileToString(getPath(tplPath),CHARSET);

        entityTpl = entityTpl.replace("User",vo.getEntityName());
        entityTpl = entityTpl.replace("user",Strings.firstLow(vo.getEntityName()));
        entityTpl = entityTpl.replace("ControllerTpl",vo.getEntityName()+"Controller");

        FileUtils.writeStringToFile(getPath(srcPath),entityTpl,CHARSET);
    }

    public static void initListHtml(GenVo vo) throws Exception {
        String tplPath = TPL_BASE_PATH + "user.html";
        String srcPath = STATIC_BASE_PATH + "html\\" + vo.getHtmlModel() +"\\"+Strings.toUnderline(Strings.firstLow(vo.getEntityName()))+".html";

        String entityTpl = FileUtils.readFileToString(getPath(tplPath),CHARSET);

        entityTpl = entityTpl.replace("User",vo.getEntityName());
        entityTpl = entityTpl.replace("user.js",Strings.toUnderline(Strings.firstLow(vo.getEntityName()))+".js");
        entityTpl = entityTpl.replace("user",Strings.firstLow(vo.getEntityName()));
        entityTpl = entityTpl.replace("用户",vo.getDesc());
        entityTpl = entityTpl.replace("basic",vo.getHtmlModel());

        FileUtils.writeStringToFile(getPath(srcPath),entityTpl,CHARSET);

        initListJs(vo);
        initAddHtml(vo);
    }

    public static void initListJs(GenVo vo) throws Exception {
        String tplPath = TPL_BASE_PATH + "user.js";
        String srcPath = STATIC_BASE_PATH + "static\\js\\" + vo.getHtmlModel() +"\\"+Strings.toUnderline(Strings.firstLow(vo.getEntityName()))+".js";

        String entityTpl = FileUtils.readFileToString(getPath(tplPath),CHARSET);

        entityTpl = entityTpl.replace("User",vo.getEntityName());
        entityTpl = entityTpl.replace("user",Strings.firstLow(vo.getEntityName()));
        entityTpl = entityTpl.replace("用户",vo.getDesc());
        entityTpl = entityTpl.replace("basic",vo.getHtmlModel());

        FileUtils.writeStringToFile(getPath(srcPath),entityTpl,CHARSET);
    }

    public static void initAddHtml(GenVo vo) throws Exception {
        String tplPath = TPL_BASE_PATH + "user_add.html";
        String srcPath = STATIC_BASE_PATH + "html\\" + vo.getHtmlModel() +"\\"+Strings.toUnderline(Strings.firstLow(vo.getEntityName()))+"_add.html";

        String entityTpl = FileUtils.readFileToString(getPath(tplPath),CHARSET);

        entityTpl = entityTpl.replace("User",vo.getEntityName());
        entityTpl = entityTpl.replace("user",Strings.firstLow(vo.getEntityName()));
        entityTpl = entityTpl.replace("用户",vo.getDesc());

        FileUtils.writeStringToFile(getPath(srcPath),entityTpl,CHARSET);
    }

    private static File getPath(String path){
        return mkdirs(path);
    }

    private static File mkdirs(String path){
        File file = new File(path);
        String directoryPath =  file.getParent();
        File directory = new File(directoryPath);
        if (!directory.exists()) {
            directory.mkdirs();
        }
        try {
            if( file.exists() ){

            }
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    public static List<GenColumn> findColumns(String tableName) throws SQLException {
        String url = "jdbc:mysql://127.0.0.1:3306/tasks?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8";
        String username = "root";
        String password = "Ab~#08ij0l1ps0!,12QQS";
        Connection conn = JdbcUtils.connect(url,username,password);

        String sql = "SELECT COLUMN_NAME,column_comment,DATA_TYPE FROM INFORMATION_SCHEMA.Columns WHERE table_name='"+tableName+"' AND table_schema='tasks'";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        ResultSet rs = pstmt.executeQuery();

        List<GenColumn> data = Lists.newArrayList();
        while (rs.next()){
            GenColumn c = new GenCode().new GenColumn();
            String columnName = rs.getString(1);
            String columnComment = rs.getString(2);
            String dataType = rs.getString(3);
            c.setColumnComment(columnComment);
            c.setColumnName(columnName);
            c.setDataType(dataType);
            data.add(c);
        }

        JdbcUtils.disconnect(conn);
        return data;
    }

    private static String dbTypeToJavaType(String dbType){
        dbType = dbType.toLowerCase();
        String value = "String";
        if( dbType.equals("bigint") || dbType.equals("int") ){
            value = "Integer";
        }else if( dbType.equals("datetime") || dbType.equals("date") ){
            value = "Date";
        }else if( dbType.equals("decimal") ){
            value = "BigDecimal";
        }
        return value;
    }

    private static String columnToProperty(String columnName){
        String[] tmps = columnName.toLowerCase().split("_");
        String property = "";
        for (int i=0 ; i<tmps.length ; i++){
            if( i == 0 ){
                property += tmps[i];
            }else{
                property += Character.toUpperCase(tmps[i].charAt(0)) + tmps[i].substring(1);
            }
        }
        return property;
    }

    @Data
    public class GenColumn {
        private String columnName;
        private String columnComment;
        private String dataType;
    }

    @Data
    public class GenVo {
        private String entityName;
        private String tableName;
        private String tablePrefix;
        private String dbType;
        private String htmlModel;
        private String desc;

        private boolean createEntity;
        private boolean createVo;
        private boolean createMapper;
        private boolean createService;
        private boolean createWeb;
    }

}
